package net.form.processing;

import java.awt.Color;
import java.util.ArrayList;
import java.util.List;

import net.form.Pixel;

public class EliminatesEdge extends AbstractImageCommand {

	/**
	 * Rango de valores HSV para determinar el fondo de la imagen
	 */
	private HSVRangeBackground rangeFondo = null;
	public EliminatesEdge(Image image, HSVRangeBackground rangeFondo) {
		super(image);
		this.rangeFondo = rangeFondo;
	}

	@Override
	public Image execute() {
		return eliminateEdge();
	}
	
	private Image eliminateEdge() {
		List<Pixel> visited =new ArrayList<Pixel>();
		for (int i = 0; i < image.getWidth(); i++) {
			if (isObject(i, 0)) {
				eliminateEdge(new Pixel(i, 0,null),visited);
			}
//			if (isObject(i, 1)) {
//				eliminateEdge(new Pixel(i, 1,null),new ArrayList<Pixel>());
//			}
//			if (isObject(i, 2)) {
//				eliminateEdge(new Pixel(i, 2,null),new ArrayList<Pixel>());
//			}
			if (isObject(i, image.getHeight() - 1)) {
				eliminateEdge(new Pixel(i, image.getHeight() - 1,null),visited);
			}
//			if (isObject(i, image.getHeight() - 2)) {
//				eliminateEdge(new Pixel(i, image.getHeight() - 2,null),new ArrayList<Pixel>());
//			}
//			if (isObject(i, image.getHeight() - 3)) {
//				eliminateEdge(new Pixel(i, image.getHeight() - 3,null),new ArrayList<Pixel>());
//			}
		}
		for (int j = 0; j < image.getHeight(); j++) {
			if (isObject(0, j)) {
				eliminateEdge(new Pixel(0, j,null),visited);
			}
//			if (isObject(1, j)) {
//				eliminateEdge(new Pixel(1, j,null),new ArrayList<Pixel>());
//			}
//			if (isObject(2, j)) {
//				eliminateEdge(new Pixel(2, j,null),new ArrayList<Pixel>());
//			}
			if (isObject(image.getWidth() - 1, j)) {
				eliminateEdge(new Pixel(image.getWidth() - 1, j,null),visited);
			}
//			if (isObject(image.getWidth() - 2, j)) {
//				eliminateEdge(new Pixel(image.getWidth() - 2, j,null),new ArrayList<Pixel>());
//			}
//			if (isObject(image.getWidth() - 3, j)) {
//				eliminateEdge(new Pixel(image.getWidth() - 3, j,null),new ArrayList<Pixel>());
//			}
		}
		return image;
	}

	private void eliminateEdge(Pixel p, List<Pixel> visited) {
		List<Pixel> neighbords = neighbords(p);
		if ( neighbords.size() == 0) {
			image.setRGB(p.getX(), p.getY(),
					rangeFondo.getColorMedio().getRGB());
//			visited.add(p);
		} else {
//			System.out.println("******* "+p.toString()+" ********");
			image.setRGB(p.getX(), p.getY(),
					rangeFondo.getColorMedio().getRGB());
			visited.add(p);
			for (int i = 0; i < neighbords.size() ; i++){
				p=neighbords.get(i);
				if(!visited.contains(p)){
					 eliminateEdge(p, visited);
				}
			}
		}
		
	}
	
	private List<Pixel> neighbords(Pixel pixel) {
		List<Pixel> points = new ArrayList<Pixel>();
//		try{
		int x = pixel.getX();
		int y = pixel.getY();
		Pixel p = null;
		if (y - 1 >= 0) {
			p = image.getPixel(x, y - 1);
			if (isObject(x, y - 1))
				points.add(0, p);
		}
		if (x + 1 < image.getWidth() && y - 1 >= 0) {
			p = image.getPixel(x + 1, y - 1);
			if (isObject(x + 1, y - 1))
				points.add(0, p);
		}
		if (x + 1 < image.getWidth()) {
			p = image.getPixel(x + 1, y);
			if (isObject(x + 1, y))
				points.add(0, p);
		}
		if (x + 1 < image.getWidth() && y + 1 < image.getHeight()) {
			p = image.getPixel(x + 1, y + 1);
			if (isObject(x + 1, y + 1))
				points.add(0, p);
		}
		if (y + 1 < image.getHeight()) {
			p = image.getPixel(x, y + 1);
			if (isObject(x, y + 1))
				points.add(0, p);
		}
		if (x - 1 >= 0 && y + 1 < image.getHeight()) {
			p = image.getPixel(x - 1, y + 1);
			if (isObject(x - 1, y + 1))
				points.add(0, p);
		}
		if (x - 1 >= 0) {
			p = image.getPixel(x - 1, y);
			if (isObject(x - 1, y))
				points.add(0, p);
		}
		if (x - 1 >= 0 && y - 1 >= 0) {
			p = image.getPixel(x - 1, y - 1);
			if (isObject(x - 1, y - 1))
				points.add(0, p);
		}
//		} catch (Exception e){
//			System.out.println();
//		}
		return points;
	}

	private boolean isBackground(int x, int y){
		Color color = new Color(image.getRGB(x, y));
		return rangeFondo.isInRange(color);
	}
	private boolean isObject(int x, int y){
		return !(isBackground(x,y));
	}
	
	@Override
	public String getCommandName() {
		return "Eliminar borde";
	}

}
